package viper.receiver.call;
/***************************************************
 * VIPER.java
 * -----------------------
 * Revision: v.2.0
 * Author: Ji Kim
 * Date Created: 12/05/2009
 * Description:
 *   Preliminary sender/receiver program that captures
 *   and digitizes audio from a microphone to create
 *   an audio data stream to be used for diversity
 *   coding and transmission.
 *   Also contains debug code for default path VoIP
 *   testing and diagnostics.
 * Last Back-Up: 01/24/10
 * Revision History: *Cleaned up and updated comments
 * 					 *Added socket-level access debug
 * 					 *Simple diversification capability
 * 					 *Improved Sender/Receiver code
 * 					 *Compatibility with custom stream/DataSource
 * 
 * Based on MediaTransmitter.java demo source code
 * in JMF package. This can be found in the link
 * provided in the tutorial at:
 * http://carfield.com.hk/document/java/tutorial
 *    /jmf_tutorial.pdf
 * -----------------------  
 ***************************************************/

import java.io.IOException;

import javax.media.CannotRealizeException;
import javax.media.Control;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoProcessorException;
import javax.media.Processor;
import javax.media.ProcessorModel;
import javax.media.control.BufferControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;


public class VIPER_Receive {

	public MediaLocator mediaLocator = null;
	public DataSink dataSink = null;
	public Processor mediaProcessor = null;

	private DataSource digitizedAudioSource;

	//Define audio codec type
	private static final Format[] FORMATS = new Format[]{
		new AudioFormat(AudioFormat.MPEG,
				44100,
				16,
				2,
				AudioFormat.BIG_ENDIAN,
				AudioFormat.SIGNED,
				8,
				8000.0,
				Format.byteArray)
	};
	//Define output of Processor
	private static final ContentDescriptor CONTENT_DESCRIPTOR =
		new ContentDescriptor(ContentDescriptor.RAW); //we just want raw data buffers

	//Constructor, define audio capture device as DataSource
	public VIPER_Receive(DataSource ds) {
		try{
			setDataSource(ds);
		}catch(CannotRealizeException cre){
			System.err.println("CannotRealizeException during construction.");
		}catch(NoProcessorException npe){
			System.err.println("NoProcessorException during construction.");
		}catch(IOException ioe){
			System.err.println("IOException during construction.");
		}
	}

	public void startEncoding() throws IOException {
		mediaProcessor.start(); //Start the Processor: encode audio data by defined codec
	}

	public void setDataSource(DataSource ds) throws IOException,
	NoProcessorException, CannotRealizeException {
		
		//Construct Processor that will handle encoding with specified codec.
		mediaProcessor = Manager.createRealizedProcessor(
				new ProcessorModel(ds, FORMATS, CONTENT_DESCRIPTOR));
		
		
		Control [] test = mediaProcessor.getControls();
		
		//Isolate the BufferControl controller from Processor and manually set buffer times.
		BufferControl bcon = (BufferControl)test[1];
		bcon.setBufferLength(16); //in ms
		
		System.out.println("::DEBUG, Buffer Length: "+bcon.getBufferLength());
		
		// Get the digitized and encoded data stream as a DataSource
		digitizedAudioSource = mediaProcessor.getDataOutput();
	}


	public DataSource getSource(){
		return digitizedAudioSource;
	}

}